"use strict";
import nodejieba from "nodejieba";
import ZONE_ARR from "./constants/zone.js";
nodejieba.load("./constant/user.dict.utf8");

const zeroLengthObj = {
  level1: 10,
  level2: 8,
  level3: 6,
  level4: 3,
};

const startCodeLength = {
  level1: 2,
  level2: 4,
  level3: 6,
  level4: 9,
};

export function getLastZoneInfo(address, isCutAll = false) {
  address = address.replace(/市辖区|海珠区/g, "");
  let addressArr = [];
  if (isCutAll) {
    addressArr = nodejieba.cutAll(address).filter((item) => item.length > 1);
  } else {
    addressArr = nodejieba.cut(address).filter((item) => item.length > 1);
  }
  const filterArr = ZONE_ARR.filter((item) =>
    addressArr.includes(item.ZONENAME)
  );
  const levelObj = getLevelInfo(filterArr);
  const [topLevelObj, topLevel] = getTopLevel(levelObj);
  const res = getLastLevelObj(levelObj, topLevelObj, topLevel);
  if (isCutAll) {
    return res || {};
  } else {
    return getLastZoneInfo(address, true) || {};
  }
}

function getLevelInfo(
  addressArr,
  level = 1,
  levelInfo = {
    level1: [],
    level2: [],
    level3: [],
    level4: [],
    level5: [],
  }
) {
  if (!addressArr.length) return levelInfo;
  const zeroString = "0".repeat(zeroLengthObj[`level${level}`]);
  const [curLevelArr, nextLevelArr] = addressArr.reduce(
    (pre, cur) => {
      if (cur.ZONE.endsWith(zeroString)) {
        pre[0].push(cur);
      } else {
        pre[1].push(cur);
      }
      return pre;
    },
    [[], []]
  );
  levelInfo[`level${level}`] = curLevelArr;
  getLevelInfo(nextLevelArr, level + 1, levelInfo);
  return levelInfo;
}

function getLastLevelObj(levelObj, topLevelObj = {}, level = 1, topZoneCode) {
  if (level === 5) return topLevelObj;
  level++;
  if (!topZoneCode) {
    topZoneCode = (topLevelObj.ZONE || "").slice(
      0,
      startCodeLength[`level${level - 1}`]
    );
  }

  const curLevelArr = levelObj[`level${level}`].filter((item) =>
    item.ZONE.startsWith(topZoneCode)
  );

  if (curLevelArr.length === 0) {
    return getLastLevelObj(levelObj, topLevelObj, level, topZoneCode);
  } else if (curLevelArr.length === 1) {
    topZoneCode = (curLevelArr[0].ZONE || "").slice(
      0,
      startCodeLength[`level${level}`]
    );
    return getLastLevelObj(levelObj, curLevelArr[0], level, topZoneCode);
  }
}

function getTopLevel(levelObj) {
  for (let i = 1; i <= 5; i++) {
    const levelLength = levelObj[`level${i}`].length;
    if (levelLength > 1) {
      return [];
    } else if (levelLength === 1) {
      return [levelObj[`level${i}`][0], i];
    }
  }
  return [];
}

function getAllLevelName(zoneCode, level = 1, res = []) {
  if (!zoneCode || level > 5) return res;
  const currentCode = zoneCode
    .slice(0, startCodeLength[`level${level}`])
    .padEnd(12, "0");
  const currentName = (ZONE_ARR.find((item) => item.ZONE === currentCode) || {})
    .ZONENAME;
  if (currentName && res[currentName.length - 1] !== currentName) {
    res.push(currentName);
    return getAllLevelName(zoneCode, ++level, res);
  } else {
    return res;
  }
}
